package sg.edu.nus.iss.jass.model;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @version 1.0
 * @author SE19 Team 1
 * 
 */
public class PropertiesDTO {
	private String id;
	
	public PropertiesDTO() {}
	
	public PropertiesDTO(String id) {
		this.id = id;
	}

	public String getId() {
		return id;
	}
	
	public void setId(String id) {
		this.id = id;
	}
	
	public Map getMap() {
		Map mapState = new HashMap();
		String strFieldName;
		String strMethodName;
		
		DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
		Field[] fields = getAllFields();
		Method method;

		for (int intCnt = 0; intCnt < fields.length; intCnt++) {
			strFieldName = fields[intCnt].getName();
			strMethodName = "get" + (char) (strFieldName.charAt(0) - 32) + strFieldName.substring(1);
			try {
				method = getMethod(strMethodName, null);
				if (method.invoke(this, (Object[])null)!=null) {
					if(method.invoke(this, (Object[])null) instanceof Date)
						mapState.put(strFieldName + getId(), df.format(method.invoke(this, (Object[])null)));
					else
						mapState.put(strFieldName + getId(), method.invoke(this, (Object[])null).toString());
				}
			}
			catch (Exception ex) {
				continue;
			}
		}
		return mapState;
	}
	
	/**
	 * Get the specified declared method in the class.
	 */
	private Method getMethod(String strMethodName, Class[] clsArg) {
		Class me = getClass();
		Class su = me.getSuperclass();
		Method method = null;
		
		try {
			method = me.getDeclaredMethod(strMethodName, clsArg);
		}
		catch (Exception ex) {
		}
		
		if (method != null) {
			return method;
		}
		do {
			try {
				method = su.getDeclaredMethod(strMethodName, clsArg);
			} catch (Exception ex) {
			}
			if (method != null) {
				return method;
			}
		} while (!(su = su.getSuperclass()).getName().equals("java.lang.Object"));
		return method;
	}
	
	/**
	 * Get all fields in the class.
	 */
	private Field[] getAllFields() {
		Class me = this.getClass();
		Class su = me.getSuperclass();
		int intLen;

		Field[] myFields = me.getDeclaredFields();
		Field[] suFields;
		Field[] fields;
		intLen = myFields.length;
		
		do {
			suFields = su.getDeclaredFields();
			intLen += suFields.length;
		} while (!(su = su.getSuperclass()).getName().equals("java.lang.Object"));

		fields = new Field[intLen];

		for (int intCnt = 0; intCnt < myFields.length; intCnt++) {
			fields[intCnt] = myFields[intCnt];
		}
		
		intLen = myFields.length;
		su = me.getSuperclass();
		do {
			suFields = su.getDeclaredFields();
			for (int intCnt = 0; intCnt < suFields.length; intCnt++) {
				fields[intLen + intCnt] = suFields[intCnt];
			}
			intLen += suFields.length;
		} while (!(su = su.getSuperclass()).getName().equals("java.lang.Object"));

		return fields;
	}

	/**
	 * Get the specified declared field in the class.
	 */
	private Field getField(String strFieldName) {
		Class me = this.getClass();
		Class su = me.getSuperclass();
		Field myField = null;
		try {
			myField = me.getDeclaredField(strFieldName);
		}
		catch (Exception ex) {
		}
		
		if (myField != null) {
			return myField;
		}
		do {
			try {
				myField = su.getDeclaredField(strFieldName);
			} catch (Exception ex) {
			}
			if (myField != null) {
				break;
			}
		} while (!(su = su.getSuperclass()).getName().equals("java.lang.Object"));

		return myField;
	}
}
